#ifndef UTILS_H
#define UTILS_H

#include <iostream>
#include <stdexcept>
#include <string>
#include <istream>
#include <sstream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <float.h>
#include <iterator>
#include <vector>
#include <stack>
#include <algorithm>

struct Timer
{
	static std::stack<clock_t> startTimes;
	static std::stack<clock_t> endTimes;
};

void beginTimer();
void endTimer();
float getTime();

int toInt(const std::string &str);
int toInt(std::istringstream &iss);
float toFloat(const std::string &str);
float toFloat(std::istringstream &iss);

std::vector<std::string> tokenize(std::string str, std::string tokens = " ");

struct Point
{
	Point(float x = 0.0f, float y = 0.0f) : x(x), y(y) { }

	float x, y;
};

// A bit pedantic to have a Vertex struct as well as a Point struct, but when
// talking about graphs in computer science, the commonly used term is
// vertex, but vertex implies more information than just an x and a y position
// that a point would give
struct Vertex
{
	Vertex(const Point &p) : p(p) {}
	Vertex(float x = 0.0f, float y = 0.0f) : p(x, y) { }

	Point p;
};

float getLengthSq(Point p1, Point p2);

struct Edge
{
	Edge() : index1(-1), index2(-1), cost(FLT_MAX) {}

	Edge(const Vertex &v1, const Vertex &v2, int index1, int index2) : index1(index1), index2(index2)
	{
		cost = getLengthSq(v1.p, v2.p);
	}

	int index1, index2;
	float cost;
};

// Compares edges
bool cmp_edge (const Edge &i, const Edge &j);

#endif
